#include "Administrator.h"


Administrator::Administrator(char *CN,char **DN,int DN_level):ClientFull(CN,DN,DN_level)
{
	opt[0] = new char[5];
	strcpy(opt[0],"-D");
}


Administrator::~Administrator(void)
{
}



void Administrator::createAccount(char *User_name,char *parola,char *user_mail)
{

	if(Auth_state)
	{
		vector<Atribut <char *>> atribute;

		char user_dn[100];

		strcpy(user_dn,"cn=");
		strcat(user_dn,User_name);
		strcat(user_dn,",ou=");
		strcat(user_dn,"people,");

		int exist = searchAccount(User_name);

		if(exist)
		{

			for(int i=0;i<DomainName_level;i++)	
			{
				strcat(user_dn,"dc=");
				strcat(user_dn,DomainName[i]);
				strcat(user_dn,",");
			}

			user_dn[strlen(user_dn)-1]=' ';

			Atribut<char *> a1("dn",user_dn),a2("objectClass","inetOrgPerson"),a3("givenName",User_name),a4("sn",parola),a5("cn",User_name),a6("mail",user_mail);

			atribute.push_back(a1);
			atribute.push_back(a2);
			atribute.push_back(a4);
			atribute.push_back(a3);
			atribute.push_back(a5);
			atribute.push_back(a6);

			char *pass = new char[strlen(LDAP_Password)+1];
			strcpy(pass,LDAP_Password);

			addEntry(ClientDN,0,pass,opt,1,atribute);

			//Intrarea default a unui client este de forma:::
			/*  dn: cn=user4,ou=people,dc=tup,dc=com
				objectClass: inetOrgPerson
				sn: user4
				givenName: user4
				cn: user4
				mail: user4email:::*/
		}
		else
		{
			printf("->The client %s already exist!",User_name);
			return;
		}
	}
	else
	{
		printf("\n\n->You must be authenticated to LDAP Server to perform this operation!!");
		return;
	}
}

int Administrator::searchAccount(char *User_name)
{
	if(Auth_state)
	{
		vector<Atribut <char *>> atribute;

		char user_dn[100];

		strcpy(user_dn,"cn=");
		strcat(user_dn,User_name);
		strcat(user_dn,",ou=");
		strcat(user_dn,"people,");

		for(int i=0;i<DomainName_level;i++)	
		{
			strcat(user_dn,"dc=");
			strcat(user_dn,DomainName[i]);
			strcat(user_dn,",");
		}

		user_dn[strlen(user_dn)-1]=' ';


		char *opts[10]={"-LLL"};
		
		Atribut<char *>a("givenName","");
		atribute.push_back(a);

		LDAP_Operation *search_op = new Search_Operation(user_dn,SIMPLE_AUTH,opts,1,"ldap:///",true , atribute);
		
		bool iResult = this->sendActionPackets(search_op->operate());

		if(iResult)
		{
			char result[300];
			strcpy(result,update());

			if(strstr(result,"NULL message"))
			{
				printf("\n->Clientul %s nu se alfa in directorul serverului LDAP...",User_name);
				return 1;
			}

			char *p=NULL,sep[]=":\n";

			Atribut<char *>a;
			vector<Atribut<char *>> atribut;

			p=strtok(result,sep);
			while(p)
			{
				a.setNume(p);
				p=strtok(NULL,sep);
				a.setValue(p+1);
				p=strtok(NULL,sep);
				atribut.push_back(a);
			}

			if(!strcmp(atribut[1].daNume(),"givenName") && !strcmp(atribut[1].daAtribut(),User_name))
			{
				printf("\n->Clientul %s este inregistrat in serverul LDAP...",User_name);
				return 0;
			}
			else
			{
				printf("\n->Clientul %s nu se alfa in directorul serverului LDAP...",User_name);
				return 1;
			}
		}
		else
		{
			printf("->Pachetul nu a putut fi trimis catre server!...");
			return 1;
		}
	}
	else
	{
		printf("\n\n->You must be authenticated to LDAP Server to perform this operation!!");
		return 1;
	}
	return 1;
}

void Administrator::deleteAccount(char *User_name)
{
	if(Auth_state)
	{
		vector<Atribut<char *>> atribute;

		char user_dn[100];

		strcpy(user_dn,"cn=");
		strcat(user_dn,User_name);
		strcat(user_dn,",ou=");
		strcat(user_dn,"people,");

		int exist = searchAccount(User_name);

		if(!exist)
		{

			for(int i=0;i<DomainName_level;i++)
			{
				strcat(user_dn,"dc=");
				strcat(user_dn,DomainName[i]);
				strcat(user_dn,",");	
			}

			user_dn[strlen(user_dn)-1]=' ';

			Atribut<char *> a1("dn",user_dn);

			atribute.push_back(a1);

			char *pass = new char[strlen(LDAP_Password)+1];
			strcpy(pass,LDAP_Password);
	
			DeleteEntry(ClientDN,0,pass,opt,1,atribute);

		}
		else
		{
			printf("->The client %s didn't found in the LDAP directory!",User_name);
			return;
		}
	}
	else
	{
		printf("\n\n->You must be authenticated to LDAP Server to perform this operation!!");
		return;
	}

}

void Administrator::Bind(char *User_name,char *Password)
{

	if(Auth_state)
	{
		printf("\nYou are already logged to LDAP Server...");
		return;
	}
	
	if(isConnected)
	{
		vector<Atribut<char*>> atribute;

		Atribut<char *> atribut("cn",User_name),atribut2("description",Password);
		atribute.push_back(atribut);
		atribute.push_back(atribut2);

		char dc[100];
		strcpy(dc,"");

		for(int i=0;i<DomainName_level;i++)
		{
			strcat(dc,"dc");
			strcat(dc,"=");
			strcat(dc,DomainName[i]);
			strcat(dc,",");
		}

		dc[strlen(dc)-1]=' ';
	
		LDAP_Operation *bind_op = new Bind_Operation(dc,atribute);

		bool iResult = this->sendActionPackets(bind_op->operate());

		Bind_Result *bind_res = new Bind_Result(this->update(),iResult,User_name,Password);

		bind_res->afisareResult();

		Auth_state = bind_res->getAuthState();
	}
	else
	{
		printf("\n\n->The user must be connected to server first!!...");
		return;
	}
}

void Administrator::addEntry(char *dn,int auth_type,char *passWord,char **optiuni,int nr_opt,vector<Atribut<char*>> atribute)
{

		if(this->password_checking(passWord))
		{

			AddEntry *addentry_op = new AddEntry(dn,auth_type,passWord,optiuni,nr_opt,atribute);
			
			LDAP_Operation *op = addentry_op->operate();

			this->sendLdifFile(addentry_op->getLdifFile());

			bool iResult = this->sendActionPackets(op);
		
			LDAP_Result *addentry_res = new LDAP_Result(this->update(),iResult);

			addentry_res->afisareResult();

			
		}
		else
		{
			printf("\n-> The LDAP Server password is wrong!!...Please try again!");
			return;
		}
	
}


void Administrator::DeleteEntry(char *dn,int auth_type,char *passWord,char **optiuni,int nr_opt,vector<Atribut <char*>> atr)
{

		if(this->password_checking(passWord))
		{

			Atribut<char *>a1("changetype","delete");
			
			atr.push_back(a1);

		
			Delete_Operation *deleteEntry_op = new Delete_Operation(dn,auth_type,passWord,optiuni,nr_opt,atr);

			LDAP_Operation *op = deleteEntry_op->operate();

			this->sendLdifFile(deleteEntry_op->getLdifFile());

	
			bool iResult = this->sendActionPackets(op);
		
			LDAP_Result *delete_res = new LDAP_Result(this->update(),iResult);

			delete_res->afisareResult();
		}
		else
		{
			printf("\n-> The LDAP Server password is wrong!!...Please try again!");
			return;
		}

}
